﻿#include "subbandtablemodel.h"
#include <QBrush>
#include <QLocale>

/**
 * @brief SubBandTableModel::setSubBands
 * @details 重置模型并替换为新的子区间数据。
 * @param rows 子区间指针列表。
 */
void SubBandTableModel::setSubBands(const QVector<TestSubBandPtr> &rows)
{
    beginResetModel();
    m_rows = rows;
    endResetModel();
}

/**
 * @brief SubBandTableModel::appendExisting
 * @details 追加一个已有的子区间对象。
 * @param sb 子区间指针。
 */
void SubBandTableModel::appendExisting(const TestSubBandPtr &sb)
{
    const int r = m_rows.size();
    beginInsertRows(QModelIndex(), r, r);
    m_rows.push_back(sb);
    endInsertRows();
}

/**
 * @brief SubBandTableModel::removeRows
 * @details 从模型中删除指定数量的子区间行。
 * @param row 起始行索引。
 * @param count 删除的行数。
 * @param parent 父索引，未使用。
 * @return 删除成功返回 true，否则为 false。
 */
bool SubBandTableModel::removeRows(int row, int count, const QModelIndex &)
{
    if (count <= 0 || row < 0 || row + count > m_rows.size())
        return false;
    beginRemoveRows(QModelIndex(), row, row + count - 1);
    for (int i = 0; i < count; ++i)
        m_rows.removeAt(row);
    endRemoveRows();
    return true;
}

/**
 * @brief SubBandTableModel::notifyRowChanged
 * @details 通知视图指定行的数据已更新。
 * @param r 行索引。
 */
void SubBandTableModel::notifyRowChanged(int r)
{
    if (r < 0 || r >= m_rows.size())
        return;
    const QModelIndex tl = index(r, 0);
    const QModelIndex br = index(r, COL_COUNT - 1);
    emit dataChanged(tl, br, {Qt::DisplayRole});
}

/**
 * @brief SubBandTableModel::rowCount
 * @details 返回当前行数。
 * @param parent 父索引，未使用。
 * @return 模型中的行数。
 */
int SubBandTableModel::rowCount(const QModelIndex &) const
{
    return m_rows.size();
}

/**
 * @brief SubBandTableModel::columnCount
 * @details 返回列数。
 * @param parent 父索引，未使用。
 * @return 模型中的列数。
 */
int SubBandTableModel::columnCount(const QModelIndex &) const
{
    return COL_COUNT;
}

/**
 * @brief SubBandTableModel::headerData
 * @details 提供表头显示数据或对齐信息。
 * @param section 列索引。
 * @param orientation 方向枚举。
 * @param role 数据角色。
 * @return 对应列的表头数据。
 */
QVariant SubBandTableModel::headerData(int section, Qt::Orientation o, int role) const
{
    if (o != Qt::Horizontal)
        return {};
    if (role == Qt::TextAlignmentRole)
        return Qt::AlignCenter;
    if (role != Qt::DisplayRole)
        return {};
    switch (section) {
    case COL_ID:
        return tr("ID");
    case COL_HW_ID:
        return tr("HW Template");
    case COL_F_START_MHZ:
        return tr("Start (MHz)");
    case COL_F_STOP_MHZ:
        return tr("Stop (MHz)");
    case COL_STEP_MHZ:
        return tr("Step (MHz)");
    case COL_DWELL_MS:
        return tr("Dwell (ms)");
    case COL_PLAN:
        return tr("Plan");
    case COL_FREQ_TABLE_ID:
        return tr("FreqTable ID");
    case COL_IMM_SRC:
        return tr("Immunity Src");
    case COL_IMM_TABLE_ID:
        return tr("ImmTbl ID");
    case COL_IMM_VALUE:
        return tr("Imm Value");
    case COL_TOL_UP_DB:
        return tr("Tol+ (dB)");
    case COL_TOL_LO_DB:
        return tr("Tol- (dB)");
    case COL_MOD:
        return tr("Modulation");
    default:
        return {};
    }
}

/**
 * @brief fmt
 * @details 使用本地化格式输出固定小数位数字。
 * @param v 数值。
 * @param decimals 小数位数。
 * @return 格式化后的字符串。
 */
static QString fmt(double v, int decimals)
{
    return QLocale().toString(v, 'f', decimals); // 固定小数位
}

/**
 * @brief SubBandTableModel::data
 * @details 根据索引与角色返回单元格数据。
 * @param idx 目标索引。
 * @param role 数据角色。
 * @return 单元格显示或属性值。
 */
QVariant SubBandTableModel::data(const QModelIndex &idx, int role) const
{
    if (!idx.isValid())
        return {};
    const int r = idx.row(), c = idx.column();
    if (r < 0 || r >= m_rows.size())
        return {};
    const auto &sb = m_rows[r];
    if (!sb)
        return {};

    if (role == Qt::TextAlignmentRole)
        return Qt::AlignCenter;
    if (role != Qt::DisplayRole)
        return {};

    switch (c) {
    case COL_ID:
        return sb->id;
    case COL_HW_ID:
        return sb->hardwareTemplateID;
    case COL_F_START_MHZ:
        return fmt(sb->startFreq / 1e6, 6);
    case COL_F_STOP_MHZ:
        return fmt(sb->stopFreq / 1e6, 6);
    case COL_STEP_MHZ:
        return fmt(sb->stepSize / 1e6, 6);
    case COL_DWELL_MS:
        return fmt(sb->dwellTime, 3);
    case COL_PLAN:
        return planToString(sb->freqPlan);
    case COL_FREQ_TABLE_ID:
        return sb->freqTableID;
    case COL_IMM_SRC:
        return immSrcToString(sb->immunityLevelType);
    case COL_IMM_TABLE_ID:
        return sb->immunityLevelTableID;
    case COL_IMM_VALUE:
        return fmt(sb->immunityLevelValue, 3);
    case COL_TOL_UP_DB:
        return fmt(sb->upperTolerance, 3);
    case COL_TOL_LO_DB:
        return fmt(sb->lowerTolerance, 3);
    case COL_MOD:
        return modToString(sb->generatorModulation);
    default:
        return {};
    }
}

/**
 * @brief SubBandTableModel::flags
 * @details 返回指定索引的项标志。
 * @param idx 目标索引。
 * @return 项标志集合。
 */
Qt::ItemFlags SubBandTableModel::flags(const QModelIndex &idx) const
{
    if (!idx.isValid())
        return Qt::NoItemFlags;
    return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}

/**
 * @brief SubBandTableModel::planToString
 * @details 将频率计划枚举转换为文本。
 * @param p 频率计划类型。
 * @return 对应的字符串描述。
 */
QString SubBandTableModel::planToString(FrequencyPlanType p)
{
    switch (p) {
    case FrequencyPlanType::SweepLinear:
        return tr("SweepLinear");
    case FrequencyPlanType::FreqTableOnly:
        return tr("FreqTableOnly");
    case FrequencyPlanType::FreqTablePlusStep:
        return tr("FreqTable+Step");
    }
    return "Unknown";
}
/**
 * @brief SubBandTableModel::immSrcToString
 * @details 将抗扰度来源枚举转换为文本。
 * @param t 抗扰度来源类型。
 * @return 对应的字符串描述。
 */
QString SubBandTableModel::immSrcToString(ImmunityLevelType t)
{
    switch (t) {
    case ImmunityLevelType::Fixed:
        return "Fixed";
    case ImmunityLevelType::Table:
        return "Table";
    }
    return "Unknown";
}
/**
 * @brief SubBandTableModel::modToString
 * @details 将信号发生器调制类型转换为文本。
 * @param m 调制类型。
 * @return 对应的字符串描述。
 */
QString SubBandTableModel::modToString(GeneratorModulationType m)
{
    switch (m) {
    case GeneratorModulationType::Off:
        return "OFF";
    case GeneratorModulationType::AM:
        return "AM";
    case GeneratorModulationType::FM:
        return "FM";
    case GeneratorModulationType::PM:
        return "PM";
    }
    return "Unknown";
}
